from django.contrib.auth import get_user_model
from rest_framework import mixins
from rest_framework import viewsets
from rest_framework import status
from rest_framework.views import APIView
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.serializers import jwt_encode_handler,jwt_payload_handler
from rest_framework.authentication import SessionAuthentication
from .serializers import UserDetailSerializer
from .serializers import UserRegistrySerializer
from .serializers import AccountUpdateSerializer
from .serializers import UserAuthGroupDetailSerializer
from .serializers import UserAuthGroupCreateSerializer
from libs.paginations import ListPagination
from images.models import push_log
from images.serializers import ImageHistoryPushRecordSerializer
from .models import Grained

User = get_user_model()


class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserRegistrySerializer
    queryset = User.objects.all().order_by('id')
    pagination_class = ListPagination
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)

    def get_serializer_class(self):
        '''
        序列化调用
        :return:
        '''

        if self.action == 'create':
            return UserRegistrySerializer
        return UserDetailSerializer

    def get_permissions(self):
        '''
        设置用户操作权限
        :return:
        '''
        if self.action == 'create':
            return [permissions.IsAdminUser(),]
        else:
            return [permissions.IsAuthenticated(),]

    def create(self, request, *args, **kwargs):
        try:
            response = request.data
            for key,value in response.items():
                if type(value) is list:
                    val = ''
                    for line in value:
                        if line != value[-1]:
                            val += line + ','
                        else:
                            val += line
                    response[key] = val
            serializer = self.get_serializer(data=response)
            serializer.is_valid(raise_exception=True)
            User.objects.create_user(**serializer.data)
            return Response(data="注册成功", status=status.HTTP_201_CREATED)

        except KeyError as e:
            return Response(data="用户字段不存在!%s"%str(e),status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        response = request.data
        for key, value in response.items():
            if type(value) is list:
                val = ''
                for line in value:
                    if line != value[-1]:
                        val += line + ','
                    else:
                        val += line
                response[key] = val
        serializer = self.get_serializer(instance, data=response, partial=partial)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}

        return Response(serializer.data)


class AccountViewSet(viewsets.GenericViewSet,
                     mixins.UpdateModelMixin):
    '''
    更改用户密码
    '''

    queryset = User.objects.all()
    serializer_class = AccountUpdateSerializer
    authentication_classes = (JSONWebTokenAuthentication,)


class UserAuthGroupViewSet(viewsets.ModelViewSet):
    '''权限组'''
    queryset = Grained.objects.all()
    pagination_class = ListPagination
    permission_classes = (permissions.IsAdminUser,)
    authentication_classes = (JSONWebTokenAuthentication,SessionAuthentication)

    def get_serializer_class(self):
        if self.action == 'create' or self.action == 'update':
            return UserAuthGroupCreateSerializer
        return UserAuthGroupDetailSerializer



class UserAuthGroupPermisstionApiView(APIView):
    '''获取单个用户的权限(过滤多个重复权限),传参 {'auth_groups':array}, auth_groups: 用户继承的权限组'''

    # def permisstions(self,val):
    #     '''过滤重复权限'''
    #     basic_grained = eval(val[0])
    #     for grained in val[1:]:
    #         for key, value in eval(grained).items():
    #             if value == '1':
    #                 basic_grained[key] = value
    #     return basic_grained

    def get(self,request,*args,**kwargs):

        from .utils.fileter_permissions import FileterUserAuth

        auth_group = self.request.query_params['auth_groups'].split(',')
        user_auth_obj = FileterUserAuth()
        return Response(user_auth_obj.to_instance(auth_group))


class UserInfoApiView(APIView):
    '''获取帐号相关信息'''

    permission_classes = (permissions.IsAuthenticated,)
    authentication_classes = (JSONWebTokenAuthentication,)

    def get(self,request,format=None):

        # 获取用户权限
        from .utils.fileter_permissions import FileterUserAuth
        user_auth_obj = FileterUserAuth()

        # 过滤掉重复权限后返回给页面进行存储
        queryset = User.objects.filter(username=self.request.user).values().first()
        auth_group = queryset.get('auth_group').split(',')
        permissions = user_auth_obj.to_instance(auth_group)
        serializer = UserDetailSerializer(queryset)
        results = serializer.data
        results['permission'] = permissions
        return Response(results)


class SystemHomeApiView(APIView):
    '''获取平台首页需要的相关数据'''

    permission_classes = (permissions.IsAuthenticated,)
    authentication_classes = (JSONWebTokenAuthentication,)

    def get(self, request, format=None):

        from systemd.models import registryInfo
        from deploy.models import work_order
        from django.db import connection

        cursor=connection.cursor()

        userCount = User.objects.all().count()
        username = self.request.user.username
        repoCount = registryInfo.objects.all().count()
        work_order_user_Count = work_order.objects.filter(submit_user=self.request.user).count()

        # 统计当月生产上线次数
        cursor.execute("select count(*) from db_view.product_deploy_record where date_format(create_time,'%Y-%m') = date_format(now(),'%Y-%m')")
        # deployCount = cursor.fetchall()   #提交
        deployCount = cursor.fetchone()[0]  #仅作检索，不提交

        uat_deploy_Count = work_order.objects.filter(env='uat').count()
        prod_deploy_Count = work_order.objects.filter(env='prod').count()

        pushRecord_obj = push_log.objects.all().order_by('-id')[:15]
        pushSerialzier = ImageHistoryPushRecordSerializer(pushRecord_obj,many=True)
        pushRecord = pushSerialzier.data

        results = {
            'userName':username,
            'userCount':userCount,
            'repoCount':repoCount,
            'deployCount':deployCount,
            'work_order_count':work_order_user_Count,
            'uat_deploy_count':uat_deploy_Count,
            'prod_deploy_count':prod_deploy_Count,
            'pushRecord':pushRecord
        }

        return Response(results)


class LdapUserLogin(APIView):
    # ldap用户验证登陆

    authentication_classes = ()
    permission_classes = ()

    def post(self, request, *args, **kwargs):
        '''
        :param request:
        :param format:
        :param args:
        :param kwargs: username: str, password: str
        :return:
        '''

        from tools.utils.LdapAuth import AuthBaseLdap

        username = request.data['username']
        password = request.data['password']
        ldap_user_auth = AuthBaseLdap(username=username, password=password)
        ldap_user_data = ldap_user_auth.BaseUserAuth()

        if ldap_user_data['status'] == "success":
            Account = User.objects.filter(username=username).first()
            if Account is None:
                users = User.objects.create_user(username=username, password=password, mobile='',
                                                 department='default', name=ldap_user_data['sn'],
                                                 role='general', auth_group='default')
                payload = jwt_payload_handler(users)
                token = jwt_encode_handler(payload)
            else:
                Account.set_password(password)
                Account.save()
                payload = jwt_payload_handler(Account)
                token = jwt_encode_handler(payload)
            return Response(status=status.HTTP_200_OK, data={'msg': '登陆成功', 'token': token})
        else:
            return Response(status=status.HTTP_400_BAD_REQUEST, data={'msg': '用户名或密码不正确，请联系管理员。'})

